package com.zzyl.nursing.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.db.PageResult;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
import com.huaweicloud.sdk.iotda.v5.model.*;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.UserThreadLocal;
import com.zzyl.nursing.domain.Device;
import com.zzyl.nursing.domain.Elder;
import com.zzyl.nursing.domain.FamilyMemberElder;
import com.zzyl.nursing.dto.DeviceDto;
import com.zzyl.nursing.dto.FamilyMemberElderDto;
import com.zzyl.nursing.dto.QueryDeviceDataDto;
import com.zzyl.nursing.mapper.DeviceDataMapper;
import com.zzyl.nursing.mapper.DeviceMapper;
import com.zzyl.nursing.mapper.ElderMapper;
import com.zzyl.nursing.mapper.FamilyMemberElderMapper;
import com.zzyl.nursing.service.IFamilyMemberElderService;
import com.zzyl.nursing.vo.FamilyMemberElderVo;
import com.zzyl.nursing.vo.FamilyMemberVo;
import com.zzyl.nursing.vo.QueryDeviceDataVo;
import com.zzyl.nursing.vo.health.PropertyStatusInfo;
import com.zzyl.nursing.vo.health.PropertyStatusInfoVo;
import com.zzyl.nursing.vo.health.PropertyStatusInfoVoList;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 老人与老人家属关联Service业务层处理
 *
 * @author alexis
 * @date 2025-03-12
 */
@Service
@Slf4j
public class FamilyMemberElderServiceImpl extends ServiceImpl<FamilyMemberElderMapper, FamilyMemberElder> implements IFamilyMemberElderService {
    @Autowired
    private FamilyMemberElderMapper familyMemberElderMapper;

    @Autowired
    private ElderMapper elderMapper;

    @Autowired
    private DeviceDataMapper deviceDataMapper;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private IoTDAClient client;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 查询老人与老人家属关联
     *
     * @param id 老人与老人家属关联主键
     * @return 老人与老人家属关联
     */
    @Override
    public FamilyMemberElder selectFamilyMemberElderById(Long id) {
        return familyMemberElderMapper.selectById(id);
    }

    /**
     * 查询老人与老人家属关联列表
     *
     * @param familyMemberElder 老人与老人家属关联
     * @return 老人与老人家属关联
     */
    @Override
    public List<FamilyMemberElder> selectFamilyMemberElderList(FamilyMemberElder familyMemberElder) {
        return familyMemberElderMapper.selectFamilyMemberElderList(familyMemberElder);
    }

    /**
     * 新增老人与老人家属关联
     *
     * @param familyMemberElder 老人与老人家属关联
     * @return 结果
     */
    @Override
    public int insertFamilyMemberElder(FamilyMemberElder familyMemberElder) {
        return familyMemberElderMapper.insert(familyMemberElder);
    }

    /**
     * 修改老人与老人家属关联
     *
     * @param familyMemberElder 老人与老人家属关联
     * @return 结果
     */
    @Override
    public int updateFamilyMemberElder(FamilyMemberElder familyMemberElder) {
        return familyMemberElderMapper.updateById(familyMemberElder);
    }

    /**
     * 批量删除老人与老人家属关联
     *
     * @param ids 需要删除的老人与老人家属关联主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberElderByIds(Long[] ids) {
        return familyMemberElderMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除老人与老人家属关联信息
     *
     * @param id 老人与老人家属关联主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberElderById(Long id) {
        return familyMemberElderMapper.deleteById(id);
    }

    /**
     * 绑定家人
     */
    @Override
    public void addFamilyMemberElder(FamilyMemberElderDto familyMemberElderDto) {
        if (ObjUtil.isNull(familyMemberElderDto)) {
            throw new BaseException("家人信息不能为空");
        }
        Elder elder = elderMapper.selectOne(new LambdaQueryWrapper<Elder>()
                .eq(Elder::getName, familyMemberElderDto.getName())
                .eq(Elder::getIdCardNo, familyMemberElderDto.getIdCard()));
        if (ObjUtil.isNull(elder)) {
            throw new BaseException("必须是养老院入住的老人的姓名和身份证号");
        }
        FamilyMemberElder familyMemberElder = new FamilyMemberElder();
        familyMemberElder.setFamilyMemberId(UserThreadLocal.get());
        familyMemberElder.setElderId(elder.getId());
        familyMemberElder.setRemark(familyMemberElderDto.getRemark());
        familyMemberElderMapper.insertFamilyMemberElder(familyMemberElder);
    }

    @Override
    public List<FamilyMemberElderVo> listFamilyMemberElder() {
        List<FamilyMemberElderVo> familyMemberElderVoList = familyMemberElderMapper.listFamilyMemberElder();
        return familyMemberElderVoList;
    }

    /**
     * 分页查询
     *
     * @param pageNum
     * @param pageSize
     */
    @Override
    public PageResult<FamilyMemberVo> getFamilyMemberElderList(Integer pageNum, Integer pageSize) {
        Page<FamilyMemberVo> page = PageHelper.startPage(pageNum, pageSize);
        List<FamilyMemberVo> resultPage = familyMemberElderMapper.selectFamilyMemberElder();

        PageResult<FamilyMemberVo> pageResult = new PageResult<>();
        pageResult.setTotal((int) page.getTotal());
        pageResult.setTotalPage(page.getPages());
        pageResult.setPage(pageNum);
        pageResult.setPageSize(pageSize);
        pageResult.addAll(resultPage);

        return pageResult;
    }

    /**
     * 按天统计查询指标数据
     */
    @Override
    public List<QueryDeviceDataVo> queryDeviceDataListByDay(QueryDeviceDataDto queryDeviceDataDto) {
        queryDeviceDataDto.setStartLocalTime(LocalDateTimeUtil.of(queryDeviceDataDto.getStartTime()));
        queryDeviceDataDto.setEndLocalTime(LocalDateTimeUtil.of(queryDeviceDataDto.getEndTime()));
        return familyMemberElderMapper.queryDeviceDataListByDay(queryDeviceDataDto);
    }

    /**
     * 按周统计查询指标数据
     *
     * @param queryDeviceDataDto
     * @return
     */
    @Override
    public List<QueryDeviceDataVo> queryDeviceDataListByWeek(QueryDeviceDataDto queryDeviceDataDto) {
        queryDeviceDataDto.setStartLocalTime(LocalDateTimeUtil.of(queryDeviceDataDto.getStartTime()));
        queryDeviceDataDto.setEndLocalTime(LocalDateTimeUtil.of(queryDeviceDataDto.getEndTime()));
        return familyMemberElderMapper.queryDeviceDataListByWeek(queryDeviceDataDto);
    }

    /**
     * 查询健康数据
     *
     * @param deviceDto
     * @return java.util.List<com.zzyl.nursing.vo.DevicePropertyStatusVo>
     */
    @Override
    public PropertyStatusInfoVoList selectHealthy(DeviceDto deviceDto) {
        List<PropertyStatusInfo> propertyStatusInfoList = new ArrayList<>();

        Device device = deviceMapper.selectOne(new LambdaQueryWrapper<Device>()
                .eq(Device::getDeviceName, deviceDto.getDeviceName()));

        ShowDeviceRequest requestDevice = new ShowDeviceRequest();
        ShowProductRequest requestProduct = new ShowProductRequest();
        requestDevice.withDeviceId(device.getIotId());
        ShowDeviceResponse showDeviceResponse = client.showDevice(requestDevice);
        requestProduct.withProductId(showDeviceResponse.getProductId());
        ShowProductResponse showProductResponse = client.showProduct(requestProduct);
        log.info("设备的信息：{}", showDeviceResponse);
        log.info("产品的信息：{}", showProductResponse);

        List<ServiceCapability> serviceCapabilities = showProductResponse.getServiceCapabilities();
        if (ObjUtil.isNull(showProductResponse) || ObjUtil.isNull(serviceCapabilities)) {
            return null;
        }

        for (ServiceCapability serviceCapability : serviceCapabilities) {
            if (serviceCapability.getProperties() == null) {
                continue;
            }
            for (ServiceProperty property : serviceCapability.getProperties()) {
                PropertyStatusInfo propertyStatusInfo = new PropertyStatusInfo();
                propertyStatusInfo.setDataType(property.getDataType());
                propertyStatusInfo.setIdentifier(property.getPropertyName());
                propertyStatusInfo.setName(property.getDescription());
                propertyStatusInfo.setUnit(property.getUnit());
                JSONArray objects = JSONUtil.parseArray(redisTemplate.opsForHash().
                        get(CacheConstants.IOT_DEVICE_LAST_DATA, device.getIotId()));
                // 将JSONArray转换为List<JSONObject>
                List<JSONObject> jsonObjectList = objects.toList(JSONObject.class);
                // 查找符合条件的所有对象
                JSONObject targetObject = jsonObjectList.stream()
                        .filter(v -> property.getPropertyName().equals(v.getStr("functionId")))
                        .findFirst()  // 只取第一个匹配的对象
                        .orElse(null);
                if (targetObject == null) {
                    continue;
                }
                // 获取所需字段的值
                String dataValue = targetObject.getStr("dataValue");
                String alarmTime = targetObject.getStr("alarmTime");
                String time = convertTime(alarmTime);
                propertyStatusInfo.setTime(time);
                propertyStatusInfo.setValue(dataValue);
                propertyStatusInfoList.add(propertyStatusInfo);
            }
        }
        PropertyStatusInfoVo propertyStatusInfoVo = new PropertyStatusInfoVo();
        propertyStatusInfoVo.setPropertyStatusInfo(propertyStatusInfoList);
        PropertyStatusInfoVoList propertyStatusInfoVoList = new PropertyStatusInfoVoList();
        propertyStatusInfoVoList.setList(propertyStatusInfoVo);
        return propertyStatusInfoVoList;

    }

    private String convertTime(String createTime) {
        if (createTime == null || createTime.isEmpty()) {
            return null;
        }
        return String.valueOf(DateUtil.parse(createTime, "yyyy-MM-dd'T'HH:mm:ss").getTime());
    }
}
